---
type: integration
title: '@astrojs/cloudflare'
description: 了解如何使用 @astrojs/cloudflare SSR 适配器来部署你的 Astro 项目。
githubIntegrationURL: 'https://github.com/withastro/adapters/tree/main/packages/cloudflare/'
category: adapter
i18nReady: true
---

import PackageManagerTabs from '~/components/tabs/PackageManagerTabs.astro'

此适配器允许 Astro 将你的[`hybrid` 或者 `server` 渲染站点](/zh-cn/basics/rendering-modes/#按需渲染)部署到[Cloudflare](https://www.cloudflare.com/).

如果你使用 Astro 作为[静态站点构建器](/zh-cn/basics/rendering-modes/#预渲染)，则不需要适配器。

在我们的 [Cloudflare Pages部署指南](/zh-cn/guides/deploy/cloudflare/) 中了解如何部署Astro站点。

## 为什么选择 Astro Cloudflare

[Cloudflare](https://www.cloudflare.com/)提供 CDN、网络安全和其他服务。该适配器增强了 Astro 构建过程，为你的项目通过 Cloudflare 进行部署做好准备。

## 安装

Astro 包含了一个 `astro add` 命令，用于自动设置官方集成。如果你愿意，可以改为[手动安装集成](#手动安装)。

在你的 Astro 项目中使用 `astro add` 命令添加 Cloudflare 适配器，以启用SSR。这将安装`@astrojs/cloudflare` 并一步到位地对你的 `astro.config.mjs` 文件进行相应的更改。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npx astro add cloudflare
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm astro add cloudflare
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn astro add cloudflare
  ```
  </Fragment>
</PackageManagerTabs>

### 手动安装

首先，使用合适的包管理器将 `@astrojs/cloudflare` 适配器添加到项目的依赖项中。

<PackageManagerTabs>
  <Fragment slot="npm">
  ```sh
  npm install @astrojs/cloudflare
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```sh
  pnpm add @astrojs/cloudflare
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```sh
  yarn add @astrojs/cloudflare
  ```
  </Fragment>
</PackageManagerTabs>

然后，将适配器和所需的[按需渲染模式](/zh-cn/basics/rendering-modes/#按需渲染)添加到 `astro.config.mjs` 文件中：

```js title="astro.config.mjs" ins={2,5-6}
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
});
```

## 选项

### imageService

<p>
**类型：** `'passthrough' | 'cloudflare' | 'compile'`<br />
**默认值：** `'passthrough'`
</p>

确定适配器使用哪个图像服务。当配置了不兼容的图像服务时，适配器将默认使用 `passthrough` 模式。否则，它将使用全局配置的图像服务：

* **`cloudflare`：** 使用 [Cloudflare 图像调整](https://developers.cloudflare.com/images/image-resizing/) 服务。
* **`passthrough`：** 使用现有的 [`noop`](/zh-cn/guides/images/#配置-no-op-透传服务) 服务。
* **`compile`：** 使用 Astro 的默认服务（sharp），但仅在构建时对预渲染的路由有效。在服务端渲染（SSR）中，对按需渲染的页面，所有 `astro:assets` 功能都将被禁用。

```js title="astro.config.mjs" ins={6}
import {defineConfig} from "astro/config";
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  adapter: cloudflare({
     imageService: 'cloudflare'
  }),
  output: 'server'
})
```

### platformProxy

决定是否以及如何将 Cloudflare 运行时添加到 `astro dev` 中。它包含对本地 `workerd` 绑定和 Cloudflare 特定值的代理和模拟，允许在 Node.js 开发过程中模拟运行时。阅读更多关于 [Cloudflare 运行时](#cloudflare-运行时) 的信息。

:::note
此处提供的代理尽最大努力模拟真实生产环境。虽然它们旨在尽可能接近真实情况，但两者之间可能存在轻微的差异和不一致。
:::

<p>
**类型：** `{ enabled?: boolean }`<br />
**默认值：** `{ enabled: false }`
</p>

`enabled` 属性允许你在 `astro dev` 中启用 Cloudflare 运行时。

#### platformProxy.configPath
<p>
**类型：** `{ configPath?: string }`<br />
**默认值：** `{ configPath: 'wrangler.toml' }`
</p>

`configPath` 允许你定义你的 Wrangler 配置文件，相对于你的 Astro 项目的根目录。

#### platformProxy.experimentalJsonConfig
<p>
**类型：** `{ experimentalJsonConfig?: boolean }`<br />
**默认值：** `{ experimentalJsonConfig?: false }`
</p>

`experimentalJsonConfig` 属性定义了该工具是否读取 JSON 配置文件（例如 `wrangler.json`）。

#### platformProxy.persist

<p>
**类型：** `{ persist?: boolean | { path: string } }`<br />
**默认值：** `{ persist: true }`
</p>

`persist` 属性定义了绑定数据是否持久化以及持久化的位置。`true` 默认与 Wrangler 使用的位置相同，因此数据可以在两者之间共享。如果是 `false`，则不会向文件系统持久化或从文件系统读取任何数据。

:::note
`wrangler` 的 `--persist-to` 选项会在底层添加一个名为 `v3` 的子目录，而 `@astrojs/cloudflare` 的 `persist` 属性则不会。例如，要重用与运行 `wrangler dev --persist-to ./my-directory` 相同的位置，你必须指定：`persist: "./my-directory/v3"`。
:::

以下配置展示了在运行开发服务器时启用 Cloudflare 运行时的示例，以及使用 `wrangler.json` 配置文件（实验性的）。它还指定了一个自定义位置，用于将数据持久化到文件系统中：


```js
import cloudflare from '@astrojs/cloudflare';
import { defineConfig } from 'astro/config';
export default defineConfig({
  adapter: cloudflare({
		platformProxy: {
			enabled: true,
			configPath: 'wrangler.json',
			experimentalJsonConfig: true,
			persist: './.cache/wrangler/v3',
		},
	}),
});
```
### routes.extend

此选项允许你添加或排除自定义模式（例如 `/fonts/*`）到生成的 [`_routes.json`](#自定义-_routesjson) 文件中，该文件决定了哪些路由是按需生成的。如果你需要添加无法自动生成的路由模式，或排除预渲染的路由，这会很有用。

关于自定义路由模式的更多信息，可以在 [Cloudflare 的路由文档](https://developers.cloudflare.com/pages/functions/routing/#functions-invocation-routes)中找到。指定的任何路由都不会自动去重，将会按原样添加到现有路由中。

#### routes.extend.include

<p>
**类型：** `{ pattern: string }[]`<br />
**默认值：** `undefined`
</p>

#### routes.extend.exclude

<p>
**类型：** `{ pattern: string }[]`<br />
**默认值：** `undefined`
</p>

在 `routes.extend.exclude` 数组中配置要从按需渲染中排除的路由。这些路由将预先渲染并以静态方式提供，而不会调用服务端渲染（SSR）函数。此外，你还可以使用这个选项直接提供任何静态资源（例如：图片、字体、css、js、html、txt、json 等）文件，无需通过 SSR 函数路由请求。

```js title="astro.config.mjs"

export default defineConfig({
  adapter: cloudflare({
    routes: {
      extend: {
        include: [{ pattern: '/static' }], // 将预渲染的页面路由到服务端渲染函数以实现按需渲染
        exclude: [{ pattern: '/pagefind/*' }], // 使用 Starlight 的 pagefind 搜索，该搜索在构建时静态生成
      }
    },
  }),
});
```

### wasmModuleImports

<p>
**类型：** `true | false`<br />
**默认值：** `false`
</p>

是否使用 `.wasm?module` 导入语法将 `.wasm` 文件[直接作为 ES 模块](https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration)导入。

将 `wasmModuleImports: true` 添加到 `astro.config.mjs` 中，以在 `astro build` 和 `astro dev` 中启用此功能。阅读更多关于[使用 Wasm 模块](#使用-wasm-模块)的信息。

```js title="astro.config.mjs" ins={6}
import {defineConfig} from "astro/config";
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  adapter: cloudflare({
     wasmModuleImports: true
  }),
  output: 'server'
})
```

## Cloudflare 运行时

Cloudflare 运行时允许你访问环境变量和 Cloudflare 绑定。
Cloudflare 运行时利用在 `wrangler` 和 `.dev.vars` 配置文件中找到的绑定。

### 用例

例如，如果你在 `wrangler.toml` 中设置了[环境变量](https://developers.cloudflare.com/workers/configuration/environment-variables/#add-environment-variables-via-wrangler)的配置：

```toml title="wrangler.toml"
[vars]
MY_VARIABLE = "test"
```

如果你还需要定义 `secrets` 以外的环境变量，你需要在 Astro 项目的根目录下添加一个 `.dev.vars` 文件：

```ini title=".dev.vars"
DB_PASSWORD=myPassword
```
你可以像这样使用 Astro locals 来访问这些绑定的值：

```astro title="src/pages/index.astro"
---
const { env } = Astro.locals.runtime;
---
```

你也可以通过 `context.locals` 从 API 端点访问运行时：

```js title="src/pages/api/someFile.js"
export function GET(context) {
  const runtime = context.locals.runtime;
  return new Response('Some body');
}
```

要访问 `MY_VARIABLE` 绑定的值，请在你的代码中添加以下内容：

```astro title="src/pages/index.astro"
---
const { env } = Astro.locals.runtime;
const myVariable = env.MY_VARIABLE;
---
```

请查看 Cloudflare 文档中的[所有支持的绑定列表](https://developers.cloudflare.com/workers/wrangler/api/#supported-bindings)。

### 类型定义

`wrangler` 提供了一个 `types` 命令来为绑定生成 TypeScript 类型。这允许你对本地变量进行类型定义，而无需手动输入它们。更多信息请参考 [Cloudflare 文档](https://developers.cloudflare.com/workers/wrangler/commands/#types)。

每次更改配置文件（例如 `wrangler.toml`、`.dev.vars`）时，你需要运行 `wrangler types`。

:::note
你可以创建一个 pnpm 脚本来自动在其他命令之前运行 `wrangler types`。

```json title="package.json"
{
  "scripts": {
    "dev": "wrangler types && astro dev",
    "start": "wrangler types && astro dev",
    "build": "wrangler types && astro check && astro build",
    "preview": "wrangler types && astro preview",
    "astro": "astro"
  }
}
```
:::

你可以使用 `Runtime` 来为 `runtime` 对象添加类型：

```ts title="src/env.d.ts"
/// <reference types="astro/client" />

type Runtime = import('@astrojs/cloudflare').Runtime<Env>;

declare namespace App {
  interface Locals extends Runtime {
    otherLocals: {
      test: string;
    };
  }
}
```

## Cloudflare 平台

### 标头

你可以通过在 Astro 项目的 `public/` 文件夹中添加一个 `_headers` 文件来附加 [自定义头部](https://developers.cloudflare.com/pages/platform/headers/) 到你的响应中，该文件将被复制到构建输出目录中。

### 资源

由 Astro 构建的所有资源都以哈希命名，因此可以为它们添加长期缓存标头。默认情况下，Cloudflare 上的 Astro 会为这些文件添加这样的头。

### 重定向

你可以使用 Cloudflare Pages 来声明 [自定义重定向](https://developers.cloudflare.com/pages/platform/redirects/)。这允许你将请求重定向到不同的 URL。你可以在 Astro 项目的 `public/` 文件夹中添加一个 `_redirects` 文件，该文件将被复制到构建输出目录。

### 路由

你可以使用 [Cloudflare 路由](https://developers.cloudflare.com/pages/platform/functions/routing/#functions-invocation-routes) 通过 `_routes.json` 文件来定义哪些路由会调用函数，哪些路由是静态资源。

#### 自定义 `_routes.json`

默认情况下，适配器会基于你应用的动态和静态路由生成一个 `_routes.json` 文件，当中包含了 `include` 和 `exclude` 规则。


这将使 Cloudflare 能够在没有函数调用的情况下提供文件和处理静态重定向。创建自定义的 `_routes.json` 将覆盖这种自动生成的文件。参阅 [Cloudflare 关于创建自定义 `routes.json` 的文档](https://developers.cloudflare.com/pages/platform/functions/routing/#create-a-_routesjson-file) 了解更多细节。

## 使用 Wasm 模块

以下是导入一个 Wasm 模块的示例，该模块通过将请求的数字参数相加来响应请求：

```js title="pages/add/[a]/[b].js"
import mod from '../util/add.wasm?module';

// 预先初始化以共享同一个模块
const addModule: any = new WebAssembly.Instance(mod);

export async function GET(context) {
  const a = Number.parseInt(context.params.a);
  const b = Number.parseInt(context.params.b);
  return new Response(`${addModule.exports.add(a, b)}`);
}
```

虽然这个例子很简单，但是 Wasm 可以用来加速在不涉及大量 I/O 的情况下的计算密集型操作，比如嵌入图像处理库。

## Node.js 兼容性

默认情况下，Cloudflare 不支持 Node.js 运行时 API。但通过一些配置，Cloudflare 可以支持 Node.js 运行时 API 的一个子集。你可以在 Cloudflare 的[文档](https://developers.cloudflare.com/workers/runtime-apis/nodejs)中找到支持的 Node.js 运行时 API。

如果要使用这些 API，你的页面或端点必须是服务器渲染的（而不是预渲染的），并使用 `import {} from 'node:*'` 导入语法。

```js title="pages/api/endpoint.js"
export const prerender = false;
import { Buffer } from 'node:buffer';
```

你还需要修改你的 astro 配置中的 `vite` 配置，以允许使用 `node:*` 导入语法：

```js title="astro.config.mjs" ins={7-11}
import {defineConfig} from "astro/config";
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  adapter: cloudflare({}),
  output: 'server',
  vite: {
		ssr: {
			external: ['node:buffer'],
		},
	},
})
```

此外，你还需要遵循 Cloudflare 的文档来启用支持。具体指导，请参考 [Cloudflare 关于启用 Node.js 兼容性的文档](https://developers.cloudflare.com/workers/runtime-apis/nodejs#enable-nodejs-with-pages-functions)。

:::note[包兼容性的影响]
如果一个项目将一个包导入到服务器中，而该包使用了 Node.js 运行时 API，这在部署到 Cloudflare 时可能会引起问题。这个问题出现在不使用 `node:*` 导入语法的包上。建议你联系包的作者，以确定该包是否支持上述导入语法。如果该包不支持这种语法，你可能需要使用另一个包。
:::

## 使用 Wrangler 预览

为了使用 [`wrangler`](https://developers.cloudflare.com/workers/wrangler/) 在本地运行你的应用程序，请更新预览脚本：

```json title="package.json"
"preview": "wrangler pages dev ./dist"
```

[`wrangler`](https://developers.cloudflare.com/workers/wrangler/) 能让你访问 [Cloudflare 绑定](https://developers.cloudflare.com/pages/platform/functions/bindings)、[环境变量](https://developers.cloudflare.com/pages/platform/functions/bindings/#environment-variables) 和 [cf 对象](https://developers.cloudflare.com/workers/runtime-apis/request/#incomingrequestcfproperties)。要让热重载或 Astro 开发服务器与 Wrangler 工作，可能需要进行自定义设置。请参阅 [社区示例](https://github.com/withastro/roadmap/discussions/590)。

### 有意义的错误消息

目前，在 Wrangler 中运行应用程序时由于代码被压缩，错误消息并不是很有用。为了更好地进行调试，你可以将 `vite.build.minify = false` 添加到你的 `astro.config.js` 文件中。

```js title="astro.config.mjs" ins={4-8}
export default defineConfig({
  adapter: cloudflare(),
  output: 'server',
  vite: {
    build: {
      minify: false,
    },
  },
});
```

[astro-integration]: /zh-cn/guides/integrations-guide/
